// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.liuxinlong.api.WeChatMessageInterface;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.SystemConstants;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.MessagePushRecordStatusEnum;
import com.liuxinlong.enums.NotificationSourceEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.BarCardDao;
import com.liuxinlong.modules.dao.ButlerTrainDao;
import com.liuxinlong.modules.dao.MessageDao;
import com.liuxinlong.modules.dao.MessagePushFailedLogDao;
import com.liuxinlong.modules.dao.MessagePushRecordDao;
import com.liuxinlong.modules.dao.MessageTargetDao;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.ParameterDao;
import com.liuxinlong.modules.dao.QuestionAnswerDao;
import com.liuxinlong.modules.dao.StandardDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.entity.BarCard;
import com.liuxinlong.modules.entity.ButlerTrain;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.MessagePushFailedLog;
import com.liuxinlong.modules.entity.MessagePushRecord;
import com.liuxinlong.modules.entity.MessageTarget;
import com.liuxinlong.modules.entity.Notification;
import com.liuxinlong.modules.entity.QuestionAnswer;
import com.liuxinlong.modules.entity.Standard;
import com.liuxinlong.modules.entity.SystemParameter;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.system.service.FileManageService;
import com.liuxinlong.modules.system.service.MessageService;
import com.liuxinlong.push.MessagePushService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 推送消息service实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年12月12日
 */
@Service
@Slf4j
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private MessageTargetDao messageTargetDao;

    @Autowired
    private WeChatMessageInterface weChatMessageInterface;

    @Autowired
    private UserDao userDao;

    @Autowired
    private BarCardDao barCardDao;

    @Autowired
    private StandardDao standardDao;

    @Autowired
    private QuestionAnswerDao questionAnswerDao;

    @Autowired
    private ButlerTrainDao butlerTrainDao;

    @Autowired
    private MessagePushService messagePushService;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private MessagePushRecordDao messagePushRecordDao;

    @Autowired
    private MessagePushFailedLogDao messagePushFailedLogDao;

    @Autowired
    private ParameterDao parameterDao;

    @Autowired
    private FileManageService fileManageService;

    @Override
    public List<Map<String, Object>> pageMessage(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<MessageConfiguration> originalList = messageDao.pageMessageList(queryParam);
        int sort = startNum + 1;
        return completeData(originalList, sort);
    }

    @Override
    public int getMessageCount(Map<String, Object> queryParam) {
        return messageDao.getMessageCount(queryParam);
    }

    @Override
    @Transactional
    public void addMessage(MessageConfiguration messageConfiguration, String targetDepartment, String targetRole, String targetUser) {
        String id = SnowFlake.nextIdStr();
        messageConfiguration.setId(id);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        messageConfiguration.setCreateUser(current.getId());
        messageConfiguration = matchBusiness(messageConfiguration, messageConfiguration.getBusinessId(), messageConfiguration.getBusinessType());
        messageDao.insert(messageConfiguration);
        List<MessageTarget> mtList = new ArrayList<>();
        if (!StringUtils.isEmpty(targetDepartment)) {
            List<String> depList = Arrays.asList(targetDepartment.split(","));
            for (String dep : depList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(1);
                mt.setRelationId(dep);
                mtList.add(mt);
            }
        }
        if (!StringUtils.isEmpty(targetRole)) {
            List<String> roleList = Arrays.asList(targetRole.split(","));
            for (String role : roleList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(2);
                mt.setRelationId(role);
                mtList.add(mt);
            }
        }
        if (!StringUtils.isEmpty(targetUser)) {
            List<String> userList = Arrays.asList(targetUser.split(","));
            for (String user : userList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(3);
                mt.setRelationId(user);
                mtList.add(mt);
            }
        }
        if (!ObjectUtils.isEmpty(mtList)) {
            messageTargetDao.insertBatch(mtList);
        }
        fileManageService.updateBusinessFile(messageConfiguration.getMediaFile(), id);
    }

    @Override
    @Transactional
    public void updateMessage(MessageConfiguration messageConfiguration, String targetDepartment, String targetRole, String targetUser) {
        String id = messageConfiguration.getId();
        MessageConfiguration oldInfo = messageDao.selectById(id);
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "消息推送配置不存在！");
        }
        if (oldInfo.getStatus() == 1) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "消息推送配置已生效，不可修改！");
//            if (oldInfo.getPushType() == 2) {
//                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR,"消息推送配置已生效，不可修改！");
//            }
//            String pushTime = oldInfo.getPushTime();
//            String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
//            SimpleDateFormat sdf = new SimpleDateFormat(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
//
//            try {
//                Date date1 = sdf.parse(pushTime);
//                Date date2 = sdf.parse(currentTime);
//                if (date1.compareTo(date2) > 0) {
//
//                }
//            }catch (ParseException e) {
//                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR,"消息推送配置时间异常！");
//            }
        }
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        messageConfiguration.setUpdateUser(current.getId());
        messageConfiguration = matchBusiness(messageConfiguration, messageConfiguration.getBusinessId(), messageConfiguration.getBusinessType());
        messageDao.updateById(messageConfiguration);
        messageTargetDao.deleteMessageTargetById(id);
        List<MessageTarget> mtList = new ArrayList<>();
        if (!StringUtils.isEmpty(targetDepartment)) {
            List<String> depList = Arrays.asList(targetDepartment.split(","));
            for (String dep : depList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(1);
                mt.setRelationId(dep);
                mtList.add(mt);
            }
        }
        if (!StringUtils.isEmpty(targetRole)) {
            List<String> roleList = Arrays.asList(targetRole.split(","));
            for (String role : roleList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(2);
                mt.setRelationId(role);
                mtList.add(mt);
            }
        }
        if (!StringUtils.isEmpty(targetUser)) {
            List<String> userList = Arrays.asList(targetUser.split(","));
            for (String user : userList) {
                MessageTarget mt = new MessageTarget();
                mt.setId(SnowFlake.nextIdStr());
                mt.setMessageId(id);
                mt.setBusinessType(3);
                mt.setRelationId(user);
                mtList.add(mt);
            }
        }
        if (!ObjectUtils.isEmpty(mtList)) {
            messageTargetDao.insertBatch(mtList);
        }
        fileManageService.updateBusinessFile(messageConfiguration.getMediaFile(), id);
    }

    @Override
    public void deleteMessage(String id) {
        messageDao.deleteById(id);
    }

    @Override
    public void updateMessageStatus(String id) {
        MessageConfiguration oldInfo = messageDao.selectById(id);
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "消息推送配置不存在！");
        }
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        if (oldInfo.getStatus() == 1) {
            if (oldInfo.getPushStatus() == 1) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "消息已推送，不可修改！");
            }
            oldInfo.setStatus(0);
            messageDao.updateById(oldInfo);
        } else {
            User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
            oldInfo.setStatus(1);
            if (oldInfo.getPushType() == 2) {
                pushMessage(oldInfo, currentTime, current);
                oldInfo.setPushTime(currentTime);
                oldInfo.setPushStatus(1);
            }
            messageDao.updateById(oldInfo);
        }
    }

    @Override
    public void addMessageAuto(String businessId, int businessType) {
        MessageConfiguration messageConfiguration = new MessageConfiguration();
        String id = SnowFlake.nextIdStr();
        messageConfiguration.setId(id);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        messageConfiguration.setCreateUser(current.getId());
        messageConfiguration.setPushType(2);
        messageConfiguration.setBusinessType(businessType);
        messageConfiguration.setBusinessId(businessId);
        messageConfiguration = matchBusiness(messageConfiguration, businessId, businessType);
        messageDao.insert(messageConfiguration);
    }

    @Override
    public Map<String, Object> queryTargetMap(String messageId) {
        Map<String, Object> query = new HashMap<>();
        query.put("messageId", messageId);
        List<MessageTarget> messageTargetList = messageTargetDao.pageMessageTargetList(query);
        List<String> departList = new ArrayList<>();
        List<String> roleList = new ArrayList<>();
        List<String> userList = new ArrayList<>();
        for (MessageTarget mt : messageTargetList) {
            if (mt.getBusinessType() == 1) {
                departList.add(mt.getRelationId());
            } else if (mt.getBusinessType() == 2) {
                roleList.add(mt.getRelationId());
            } else if (mt.getBusinessType() == 3) {
                userList.add(mt.getRelationId());
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(departList)) {
            resultMap.put("1", departList);
        }
        if (!ObjectUtils.isEmpty(roleList)) {
            resultMap.put("2", roleList);
        }
        if (!ObjectUtils.isEmpty(userList)) {
            resultMap.put("3", userList);
        }
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> queryBusinessList(String businessType) {
        int type = Integer.parseInt(businessType);
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("startNum", 0);
        queryParam.put("pageSize", 10000);
        if (type == 1) {
            List<BarCard> barCards = barCardDao.getBarCardManageList(queryParam);
            for (BarCard barCard : barCards) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", barCard.getId());
                map.put("label", barCard.getTitle());
                map.put("value", barCard.getId());
                map.put("name", barCard.getTitle());
                resultList.add(map);
            }
        } else if (type == 2) {
            List<Standard> standardList = standardDao.getStandardList();
            for (Standard standard : standardList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", standard.getId());
                map.put("label", standard.getName());
                map.put("value", standard.getId());
                map.put("name", standard.getName());
                resultList.add(map);
            }
        } else if (type == 3) {
            List<QuestionAnswer> questionAnswerList = questionAnswerDao.getQuestionAnswerList();
            for (QuestionAnswer questionAnswer : questionAnswerList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", questionAnswer.getId());
                map.put("label", questionAnswer.getQuestion());
                map.put("value", questionAnswer.getId());
                map.put("name", questionAnswer.getQuestion());
                resultList.add(map);
            }
        } else {
            queryParam.put("businessType", type - 2);
            List<ButlerTrain> butlerTrainList = butlerTrainDao.pageTrainInfo(queryParam);
            for (ButlerTrain butlerTrain : butlerTrainList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", butlerTrain.getId());
                map.put("label", butlerTrain.getTitle());
                map.put("value", butlerTrain.getId());
                map.put("name", butlerTrain.getTitle());
                resultList.add(map);
            }
        }

        return resultList;
    }

    @Override
    public void delayedSendingMessage() {
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        List<MessageConfiguration> mcList = messageDao.queryPendingList(currentTime.substring(0, 16));
        if (ObjectUtils.isEmpty(mcList)) {
            return;
        }
        List<MessageConfiguration> successList = new ArrayList<>();
        for (MessageConfiguration mc : mcList) {
            String userId = StringUtils.isEmpty(mc.getUpdateUser()) ? mc.getCreateUser() : mc.getUpdateUser();
            User pushUser = userDao.selectById(userId);
            pushMessage(mc, currentTime, pushUser);
            mc.setPushTime(currentTime);
            mc.setPushStatus(1);
            successList.add(mc);
        }
        messageDao.updateBatchById(successList);
    }

    @Override
    @Transactional
    public void revokeMessage(String id, String messageId) {
        MessagePushRecord mpr;
        if (ObjectUtils.isEmpty(id)) {
            mpr = messagePushRecordDao.getLatestRecord(messageId);
        } else {
            mpr = messagePushRecordDao.selectById(id);
        }
        if (ObjectUtils.isEmpty(mpr)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "撤回失败，推送记录不存在！");
        }
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        if (TimeUtils.calculateTimeGapSecond(mpr.getPushTime(), currentTime, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS) > 24 * 60 * 60) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "撤回失败，推送记录已超过24小时！");
        }
        weChatMessageInterface.recallMessage(mpr.getMsgId());
        mpr.setStatus(MessagePushRecordStatusEnum.RECALLED.getValue());
        messagePushRecordDao.updateById(mpr);
        notificationDao.revokeByRecordId(mpr.getId());
        MessageConfiguration mc = messageDao.selectById(mpr.getMessageId());
        mc.setPushStatus(2);
        mc.setStatus(0);
        messageDao.updateById(mc);
    }

    @Override
    public void exportMessageList(HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("菜单信息列表导出excel.xlsx");
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("startNum", 0);
        queryParam.put("pageSize", 10000);
        List<MessageConfiguration> messageList = messageDao.pageMessageList(queryParam);
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        String[] head = {"序号", "消息标题", "消息来源", "消息内容", "创建人", "推送类型", "推送时间", "推送状态", "目标受众", "状态", "操作人", "操作时间"};
        data.setHead(head);
        String[][] dataList = new String[messageList.size()][head.length];
        int index = 0;
        for (MessageConfiguration item : messageList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = item.getTitle();
            dataList[index][2] = MessagePushBusinessEnum.getNameByValue(item.getBusinessType());
            dataList[index][3] = item.getContent();

            dataList[index][4] = item.getShareUser();
            dataList[index][5] = item.getPushType() == 1 ? "定时推送" : "立即推送";
            dataList[index][6] = item.getPushTime();
            dataList[index][7] = item.getPushStatus() == 0 ? "未推送" : "已推送";
            List<String> targetList = Arrays.asList(item.getTarget().split(","));
            String targetName = "";
            for (String s : targetList) {
                if (StringUtils.equals("1", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "部门" : targetName + "，部门";
                } else if (StringUtils.equals("2", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "角色" : targetName + "，角色";
                } else if (StringUtils.equals("3", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "用户" : targetName + "，用户";
                }
            }
            dataList[index][8] = targetName;
            dataList[index][9] = item.getStatus() == 0 ? "未启用" : "已启用";
            dataList[index][10] = userMap.containsKey(item.getCreateUser()) ? userMap.get(item.getCreateUser()).get("name") : "-";
            dataList[index][11] = item.getCreateTime();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public List<Map<String, Object>> pageMessagePushRecord(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<MessagePushRecord> messagePushRecordList = messagePushRecordDao.pageMessageRecordList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(messagePushRecordList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        int sort = startNum + 1;
        for (MessagePushRecord mpr : messagePushRecordList) {
            Map<String, Object> item = ObjectUtils.object2Map(mpr);
            item.put("sort", sort);
            item.put("operateUserName", userMap.containsKey(mpr.getOperateUser()) ? userMap.get(mpr.getOperateUser()).get("name") : "-");
            item.put("statusName", MessagePushRecordStatusEnum.getNameByValue(mpr.getStatus()));
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getMessagePushRecordCount(Map<String, Object> queryParam) {
        return messagePushRecordDao.getMessageRecordCount(queryParam);
    }

    @Override
    public void packageSendingMessage() {
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM);
        SystemParameter sp = parameterDao.getParameterByName(SystemConstants.CURRENT_SYSTEM_IP);
        if (ObjectUtils.isEmpty(sp)) {
            throw new AosException(ReturnCodes.HTTP_SYSTEM_ERROR);
        }
        String wechatMessage = "【RDKS提醒】\n"
                + "互动通知\n"
                + "您有未读新消息，详情登陆RDKS查看\n"
                + "创建人：系统\n"
                + "时间：" + currentTime + "\n"
                + "<a href=\"" + sp.getValue() + "\">点击链接登陆>></a>";
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("startNum", 0);
        queryParam.put("pageSize", 10000);
        queryParam.put("status", 0);
        queryParam.put("sourceType", 1);
        queryParam.put("startTime", TimeUtils.beforeOneHourToNowDate(currentTime, TimeFormatConstants.YYYY_MM_DD_HH_MM));
        queryParam.put("endTime", currentTime);
        List<Notification> unreadList = notificationDao.queryInteractiveNotification(queryParam);
        Set<String> targetUserSet = unreadList.stream().map(Notification::getDealUser).collect(Collectors.toSet());
        MessageConfiguration messageConfiguration = new MessageConfiguration();
        messageConfiguration.setBusinessType(MessagePushBusinessEnum.INTERACTIVE.getValue());
        messageConfiguration.setContent("您有未读新消息，详情登陆RDKS查看");
        messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
        weChatMessageInterface.pushMessage(new ArrayList<>(targetUserSet), null, messageConfiguration, currentTime);
    }

    @Override
    public List<Map<String, Object>> pageMessagePushFailedLog(Map<String, Object> queryParam) {
        List<MessagePushFailedLog> failedLogList = messagePushFailedLogDao.pagePushFailedLogList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(failedLogList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        int startNum = (int) queryParam.get("startNum");
        int sort = startNum + 1;
        for (MessagePushFailedLog failedLog : failedLogList) {
            Map<String, Object> item = ObjectUtils.object2Map(failedLog);
            item.put("sort", sort);
            item.put("userName", userMap.containsKey(failedLog.getUserId()) ? userMap.get(failedLog.getUserId()).get("name") : "");
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getMessagePushFailedLogCount(Map<String, Object> queryParam) {
        return messagePushFailedLogDao.getMessagePushFailedLogCount(queryParam);
    }

    /**
     * 数据补全
     *
     * @param originalList 原始数据
     * @param sort         序号
     * @return 补全后数据
     */
    private List<Map<String, Object>> completeData(List<MessageConfiguration> originalList, int sort) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        List<UserRoleRelation> roleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        boolean superPermission = false;
        if (!ObjectUtils.isEmpty(roleRelationList)) {
            for (UserRoleRelation userRoleRelation : roleRelationList) {
                if (StringUtils.equals(userRoleRelation.getRoleId(),"1" )) {
                    superPermission = true;
                }
            }
        }
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        List<Map<String, Object>> resultList = new ArrayList<>(originalList.size());
        for (MessageConfiguration mc : originalList) {
            Map<String, Object> item = ObjectUtils.object2Map(mc);
            item.put("sort", sort);
            item.put("businessTypeName", MessagePushBusinessEnum.getNameByValue(mc.getBusinessType()));
            List<String> targetList = Arrays.asList(mc.getTarget().split(","));
            String targetName = "";
            boolean ownerPermission = StringUtils.equals(mc.getCreateUser(), currentUser.getId());
            for (String s : targetList) {
                if (StringUtils.equals("1", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "部门" : targetName + "，部门";
                } else if (StringUtils.equals("2", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "角色" : targetName + "，角色";
                } else if (StringUtils.equals("3", s)) {
                    targetName = StringUtils.isEmpty(targetName) ? "用户" : targetName + "，用户";
                }
            }
            item.put("targetName", targetName);
            item.put("createUserName", userMap.containsKey(mc.getCreateUser()) ? userMap.get(mc.getCreateUser()).get("name") : "-");
            item.put("operatePermission", ownerPermission || superPermission);
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    /**
     * 匹配业务信息
     *
     * @param messageConfiguration 消息推送配置
     * @param businessId           业务id
     * @param businessType         业务类型
     * @return 消息配置
     */
    private MessageConfiguration matchBusiness(MessageConfiguration messageConfiguration, String businessId, int businessType) {
        boolean contentChange = false;
        boolean userChange = false;
        if (StringUtils.isEmpty(messageConfiguration.getContent())) {
            contentChange = true;
        }
        if (StringUtils.isEmpty(messageConfiguration.getShareUser())) {
            userChange = true;
        }
        if (businessType == MessagePushBusinessEnum.CHIMI.getValue()) {
            BarCard barCard = barCardDao.selectById(businessId);
            if (contentChange) {
                messageConfiguration.setContent(barCard.getTitle());
            }
            if (userChange) {
                User user = userDao.selectById(barCard.getCreateUser());
                messageConfiguration.setShareUser(ObjectUtils.isEmpty(user) ? "" : user.getName());
            }
        } else if (businessType == MessagePushBusinessEnum.STANDARD.getValue()) {
//            Standard standard = standardDao.selectById(businessId);
//            if (contentChange) {
//                messageConfiguration.setContent(standard.getName());
//            }
//            if (userChange) {
//                User user = userDao.selectById(standard.getCreateUser());
//                messageConfiguration.setShareUser(ObjectUtils.isEmpty(user) ? "" : user.getName());
//            }
            if (StringUtils.isEmpty(messageConfiguration.getTitle())) {
                messageConfiguration.setTitle("NA");
            }
            messageConfiguration.setShareUser("系统");
        } else if (businessType == MessagePushBusinessEnum.BUTLER_FAQ.getValue()) {
            QuestionAnswer questionAnswer = questionAnswerDao.selectById(businessId);
            if (contentChange) {
                messageConfiguration.setContent(questionAnswer.getQuestion());
            }
            if (userChange) {
                User user = userDao.selectById(StringUtils.isEmpty(questionAnswer.getUpdateUser()) ? questionAnswer.getCreateUser() : questionAnswer.getUpdateUser());
                messageConfiguration.setShareUser(ObjectUtils.isEmpty(user) ? "" : user.getName());
            }
        } else if (businessType == MessagePushBusinessEnum.OTHER.getValue() || businessType == MessagePushBusinessEnum.PATENT_MODULE.getValue() || businessType == MessagePushBusinessEnum.PATENT_TRENDS.getValue()) {
            if (StringUtils.isEmpty(messageConfiguration.getTitle())) {
                messageConfiguration.setTitle("NA");
            }
            messageConfiguration.setShareUser("系统");
        } else if (businessType == MessagePushBusinessEnum.EXPERT_MODULE.getValue() ) {
            if (StringUtils.isEmpty(messageConfiguration.getTitle())) {
                messageConfiguration.setTitle("NA");
            }
            User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
            messageConfiguration.setShareUser(currentUser.getName());
//        }  else if (businessType == MessagePushBusinessEnum.PATENT_MODULE.getValue() ) {
//            if (StringUtils.isEmpty(messageConfiguration.getTitle())) {
//                messageConfiguration.setTitle("NA");
//            }
//            User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
//            messageConfiguration.setShareUser(currentUser.getName());
//        }  else if (businessType == MessagePushBusinessEnum.PATENT_TRENDS.getValue() ) {
//            if (StringUtils.isEmpty(messageConfiguration.getTitle())) {
//                messageConfiguration.setTitle("NA");
//            }
//            User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
//            messageConfiguration.setShareUser(currentUser.getName());
        } else {
            ButlerTrain butlerTrain = butlerTrainDao.selectById(businessId);
            if (contentChange) {
                messageConfiguration.setContent(butlerTrain.getTitle());
            }
            if (userChange) {
                messageConfiguration.setShareUser(butlerTrain.getShareUser());
            }
        }
        return messageConfiguration;
    }

    /**
     * 推送消息
     *
     * @param oldInfo     消息推送配置
     * @param currentTime 当前时间
     * @param current     当前用户
     */
    private void pushMessage(MessageConfiguration oldInfo, String currentTime, User current) {
        List<String> targetList = getPushUsers(oldInfo);
        pushMessageToWeb(oldInfo, targetList);
        SystemParameter sp = parameterDao.getParameterByName(SystemConstants.CURRENT_SYSTEM_IP);
        if (ObjectUtils.isEmpty(sp)) {
            throw new AosException(ReturnCodes.HTTP_SYSTEM_ERROR);
        }
//        String wechatMessage = "【RDKS提醒】\n"
//                + MessagePushBusinessEnum.getWechatNameByValue(oldInfo.getBusinessType()) + "\n"
//                + oldInfo.getContent() + "\n"
//                + "创建人：" + oldInfo.getShareUser() + "\n"
//                + "时间：" + currentTime + "\n"
//                + "<a href=\"" + sp.getValue() +"\">点击链接登陆>></a>";
        String wechatMessage =
                "<div class=\"normal\">" + MessagePushBusinessEnum.getWechatNameByValue(oldInfo.getBusinessType()) +
                        "</div><div class=\"gray\">" + currentTime +
                        "</div> <div class=\"highlight\">" + oldInfo.getContent() +
                        "</div><div class=\"normal\">" + "创建人：" + oldInfo.getShareUser() + "</div>";
//
        String mprId = SnowFlake.nextIdStr();
        MessagePushRecord mpr = weChatMessageInterface.pushMessage(targetList, mprId, oldInfo, currentTime);
        mpr.setId(mprId);
        mpr.setMessageId(oldInfo.getId());
        mpr.setPushTime(currentTime);
        mpr.setOperateUser(current.getId());
        messagePushRecordDao.insert(mpr);
        List<Notification> notificationList = new ArrayList<>(targetList.size());
        int sourceType = oldInfo.getBusinessType() == MessagePushBusinessEnum.CHIMI.getValue() ? NotificationSourceEnum.CHIMI_CARD.getValue() :
                oldInfo.getBusinessType() == MessagePushBusinessEnum.STANDARD.getValue() ? NotificationSourceEnum.STANDARD.getValue() :
                        oldInfo.getBusinessType() == MessagePushBusinessEnum.OTHER.getValue() ? NotificationSourceEnum.SYSTEM.getValue() :
                                oldInfo.getBusinessType() == MessagePushBusinessEnum.EXPERT_MODULE.getValue() ? NotificationSourceEnum.EXPERT_MODULE.getValue() :
                                        oldInfo.getBusinessType() == MessagePushBusinessEnum.PATENT_MODULE.getValue() ? NotificationSourceEnum.PATENT_MODULE.getValue() :
                                                oldInfo.getBusinessType() == MessagePushBusinessEnum.PATENT_TRENDS.getValue() ? NotificationSourceEnum.PATENT_TRENDS.getValue() :
                                                        NotificationSourceEnum.BUTLER.getValue();
        for (String targetId : targetList) {
            Notification notification = new Notification();
            notification.setId(SnowFlake.nextIdStr());
            notification.setDealUser(targetId);
            notification.setSourceId(oldInfo.getBusinessId());
            notification.setSourceType(sourceType);
            notification.setRecordId(mprId);
            notification.setCreateUser(current.getId());
            String content = oldInfo.getContent();
            if (sourceType == NotificationSourceEnum.CHIMI_CARD.getValue() || sourceType == NotificationSourceEnum.BUTLER.getValue()) {
                content = oldInfo.getShareUser() + " 在 " + NotificationSourceEnum.getSourceNameByValue(sourceType) + " 发布了 " + oldInfo.getTitle();
            }
            notification.setContent(content);
            notification.setCreateTime(currentTime);
            notificationList.add(notification);
        }
        if (ObjectUtils.isEmpty(notificationList)) {
            return;
        }
        notificationDao.insertBatch(notificationList);
    }

    /**
     * 批量推送信息到用户页面
     *
     * @param messageConfiguration 消息配置
     */
    private List<String> getPushUsers(MessageConfiguration messageConfiguration) {
        String target = messageConfiguration.getTarget();
        List<String> targetList = new ArrayList<>();
        if (target.contains("1")) {
            Map<String, Object> queryParam = new HashMap<>();
            queryParam.put("messageId", messageConfiguration.getId());
            queryParam.put("businessType", 1);
            List<MessageTarget> messageTargetDepList = messageTargetDao.pageMessageTargetList(queryParam);
            List<String> depList = messageTargetDepList.stream().map(MessageTarget::getRelationId).collect(Collectors.toList());
            List<String> depUserList = userDao.getUserByDeps(depList);
            targetList.addAll(depUserList);
        }
        if (target.contains("2")) {
            Map<String, Object> queryParam = new HashMap<>();
            queryParam.put("messageId", messageConfiguration.getId());
            queryParam.put("businessType", 2);
            List<MessageTarget> messageTargetRoleList = messageTargetDao.pageMessageTargetList(queryParam);
            List<String> roleList = messageTargetRoleList.stream().map(MessageTarget::getRelationId).collect(Collectors.toList());
            List<String> roleUserList = userRoleRelationDao.getUserByRoles(roleList);
            targetList.addAll(roleUserList);
        }
        if (target.contains("3")) {
            Map<String, Object> queryParam = new HashMap<>();
            queryParam.put("messageId", messageConfiguration.getId());
            queryParam.put("businessType", 3);
            List<MessageTarget> messageTargetUserList = messageTargetDao.pageMessageTargetList(queryParam);
            List<String> userList = messageTargetUserList.stream().map(MessageTarget::getRelationId).collect(Collectors.toList());
            targetList.addAll(userList);
        }
        List<String> messageTargetList = new ArrayList<>(targetList.stream().collect(Collectors.toSet()));
        return messageTargetList;
    }

    /**
     * 批量推送信息到用户页面
     *
     * @param messageConfiguration 消息配置
     * @param messageTargetList    目标用户列表
     */
    private void pushMessageToWeb(MessageConfiguration messageConfiguration, List<String> messageTargetList) {
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        Map<String, String> contentMap = new HashMap<>();
        contentMap.put("title", "您有一条新消息待查看");
        contentMap.put("description", messageConfiguration.getContent());
        String content = JSON.toJSONString(contentMap);
        for (String mt : messageTargetList) {
            if (!userMap.containsKey(mt)) {
                continue;
            }
            String userSn = userMap.get(mt).get("sn");
            messagePushService.pushMessage(content, userSn);
        }
    }
}
